Conversation
| } | ||
|
|
||
| // Guide the fuzzer towards a single valid enum | ||
| int index = Math.floorMod(candidate.hashCode(), constants.length); |
There was a problem hiding this comment.
This can jump around when candidate changes slightly, which could throw off the guidance. Instead, you could use a ClassValue to associate an Enum class with a sorted array of its values and then Arrays.binarySearch for the nearest valid value (perhaps ignoring case).
There was a problem hiding this comment.
I am curious about the reasoning to go for the nearest enum value--why prefer it over any other enum value?
I am asking because I think there is a bias in libfuzzer's output (e.g. zeros are way more favored than anything else), and by taking the closest value, this bias gets propagated. WDYT?
There was a problem hiding this comment.
Picking the nearest candidate isn't necessary, but I think that a particular guideTowardsEquality call (with a fixed hook id) should keep guiding towards the same target as long as the fuzzer keeps making progress towards the target tracked in the last iteration. I could see the behavior becoming erratic if the target changes as more bytes agree.
There was a problem hiding this comment.
I benchmarked the 3 solutions (binary search, random pick, hashcode based pick) by executing 50 times a fresh fuzz test with 1M executions.
It seems like distribution is slightly more spread in the binary search but not by a large margin. On the other hand it does increases the complexity.
Binary search with random pick for the neighbour:
SUPER_SECRET_SHADE hits=76401
YELLOW hits=191745
BBB hits=584921
CCC hits=484576
DDD hits=480848
EEE hits=514521
Total hits across all enum constants: 2333012
Hashcode pick (random pick has also very similar values):
SUPER_SECRET_SHADE hits=66965
YELLOW hits=163662
BBB hits=556240
CCC hits=547206
DDD hits=541491
EEE hits=536563
Total hits across all enum constants: 2412127
There was a problem hiding this comment.
Arrays.binarySearch
To be stable with binary search, we would need the fuzzer to makes small changes at the end of the string, or am I missing something?
Ideally, we would probably use something like the edit-distance, but that seems expensive.
In the end, we decided to keep the fuzzer feedback "candidate-stable", aka the hashCode solution above!
My idea was to use random guidance, because the purpose here is to guide towards a valid enum, and nothing else. Stability is not an issue because TORC will either 1) be used properly and completely replace the string (and generate a correct enum) or 2) be used to replace the string partially and most likely not a correct enum value.
Drawing a random number is (probably) faster than computing the hashcode of a string, so I think this solution would be the best, but it lost!
src/main/java/com/code_intelligence/jazzer/runtime/TraceCmpHooks.java
Outdated
Show resolved
Hide resolved
src/main/java/com/code_intelligence/jazzer/runtime/TraceCmpHooks.java
Outdated
Show resolved
Hide resolved
b4c8d2a to
ca81c4d
Compare
Add a hook to guide
Enum.valueOftoward a valid enum name by deterministically picking a single candidate from the enum list